package com.camera.yl.service

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.lifecycle.lifecycleScope
import com.camera.base.Log.YLogImpl
import com.camera.base.dao.ActualFile
import com.camera.base.dao.UploadQueue
import com.camera.base.dao.UploadQueueDaoHelper
import com.camera.device.dao.ActualFileDaoHelper
import com.camera.base.inerface.FileUploadListener
import com.camera.routemodule.routeinterface.RouterUtil
import com.camera.yl.R
import com.camera.yl.manager.UploadManager
import com.camera.yl.models.UploadStatus
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import java.io.File
import java.util.concurrent.ConcurrentHashMap

/**
 * 上传服务
 * 管理上传队列，执行文件上传任务
 */
class UploadService : Service() {
    
    companion object {
        private const val TAG = "UploadService"
        private const val NOTIFICATION_ID = 1001
        private const val CHANNEL_ID = "upload_channel"
        private const val CHANNEL_NAME = "文件上传"
        
        // 文件类型常量
        private const val FILE_TYPE_VIDEO = 1  // 视频文件
        private const val FILE_TYPE_IMAGE = 2  // 图片文件
    }
    
    private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
    
    // 当前上传任务的监听器映射
    private val uploadListeners = ConcurrentHashMap<String, FileUploadListener>()
    
    // 正在上传的文件计数器
    private var uploadingCount = 0
    
    /**
     * 检查是否所有文件都完成上传
     */
    private fun checkAllUploadsComplete() {
        uploadingCount--
        YLogImpl.d(TAG, "文件上传完成，剩余文件数: $uploadingCount")
        
        if (uploadingCount <= 0) {
            YLogImpl.i(TAG, "所有文件上传完成")
            stopSelf()
        }
    }
    
    override fun onCreate() {
        super.onCreate()
        YLogImpl.i(TAG, "UploadService创建")
        createNotificationChannel()
    }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        YLogImpl.i(TAG, "启动上传服务")
        
        // 创建前台通知
        startForeground(NOTIFICATION_ID, createNotification("准备上传文件..."))
        
        intent?.getStringArrayListExtra("file_paths")?.let { filePaths ->
            serviceScope.launch {
                processUploadQueue(filePaths)
            }
        }
        
        return START_STICKY
    }
    
    override fun onBind(intent: Intent?): IBinder? = null
    
    override fun onDestroy() {
        YLogImpl.i(TAG, "UploadService销毁")
        serviceScope.cancel()
        super.onDestroy()
    }
    
    /**
     * 处理上传队列
     */
    private suspend fun processUploadQueue(filePaths: List<String>) {
        YLogImpl.i(TAG, "开始处理上传队列，共${filePaths.size}个文件")
        
        // 将文件添加到上传队列数据库
        addFilesToUploadQueue(filePaths)
        
        // 开始上传
        startUploading()
    }
    
    /**
     * 将文件添加到上传队列数据库
     */
    private suspend fun addFilesToUploadQueue(filePaths: List<String>) {
        filePaths.forEach { filePath ->
            try {
                YLogImpl.d(TAG, "准备添加文件到上传队列: $filePath")
                
                // 通过文件路径查找对应的ActualFile记录
                val actualFile = ActualFileDaoHelper.getByPath(filePath)
                if (actualFile != null) {
                    YLogImpl.d(TAG, "找到ActualFile记录: uid=${actualFile.uid}, path=${actualFile.path}, upload=${actualFile.upload}")
                    
                    // 检查文件是否已经上传
                    if (actualFile.upload == 0) {
                        YLogImpl.d(TAG, "文件已上传，跳过: $filePath")
                        return@forEach
                    }
                    
                    // 检查是否已存在相同的actualFileId记录
                    val existingQueue = UploadQueueDaoHelper.getByActualFileId(actualFile.uid)
                    if (existingQueue != null) {
                        YLogImpl.d(TAG, "文件已在上传队列中: $filePath, actualFileId: ${actualFile.uid}")
                        return@forEach
                    }
                    
                    // 创建上传队列记录
                    val uploadQueue = UploadQueue().apply {
                        this.actualFileId = actualFile.uid
                        this.path = filePath
                        this.uploadType = 0  // 0表示HTTP上传
                        this.priority = 0
                        this.createdTime = System.currentTimeMillis()
                        this.updatedTime = System.currentTimeMillis()
                    }
                    
                    // 插入到数据库
                    val success = UploadQueueDaoHelper.insert(uploadQueue)
                    if (success) {
                        YLogImpl.d(TAG, "添加到上传队列成功: $filePath, actualFileId: ${actualFile.uid}")
                    } else {
                        YLogImpl.e(TAG, "添加到上传队列失败: $filePath")
                    }
                } else {
                    YLogImpl.w(TAG, "未找到对应的ActualFile记录: $filePath")
                    YLogImpl.w(TAG, "跳过此文件，无法上传")
                    
                    // 清理UploadManager中的状态（移除PENDING状态）
                    UploadManager.updateUploadStatus(filePath, UploadStatus.FAILED, 0, "文件记录不存在，无法上传")
                    
                    // 检查UploadQueue表中是否有孤儿记录并删除
                    try {
                        // 通过路径查找可能存在的孤儿记录
                        val allUploads = UploadQueueDaoHelper.getByUploadType(0)
                        allUploads?.find { it.path == filePath }?.let { orphanRecord ->
                            YLogImpl.d(TAG, "发现孤儿记录，准备删除: $filePath, uid: ${orphanRecord.uid}")
                            val deleteSuccess = UploadQueueDaoHelper.delete(orphanRecord.uid)
                            if (deleteSuccess) {
                                YLogImpl.d(TAG, "删除孤儿记录成功: $filePath, uid: ${orphanRecord.uid}")
                            } else {
                                YLogImpl.e(TAG, "删除孤儿记录失败: $filePath, uid: ${orphanRecord.uid}")
                            }
                        }
                    } catch (e: Exception) {
                        YLogImpl.e(TAG, "清理孤儿记录异常: $filePath", e)
                    }
                }
            } catch (e: Exception) {
                YLogImpl.e(TAG, "添加文件到上传队列异常: $filePath", e)
            }
        }
    }
    
    /**
     * 开始上传任务
     */
    private suspend fun startUploading() {
        serviceScope.launch(Dispatchers.IO) {
            try {
                // 获取所有待上传的文件
                val allPendingUploads = UploadQueueDaoHelper.getByUploadType(0) // HTTP上传
                
                if (allPendingUploads?.isEmpty() != false) {
                    YLogImpl.i(TAG, "没有待上传的文件")
                    stopSelf()
                    return@launch
                }
                
                YLogImpl.i(TAG, "检查上传队列，共${allPendingUploads.size}个文件")
                
                // 清理已经上传的文件
                val validPendingUploads = mutableListOf<UploadQueue>()
                var cleanedCount = 0
                
                allPendingUploads.forEach { uploadQueue ->
                    try {
                        // 检查对应的ActualFile是否已经上传
                        val actualFile = ActualFileDaoHelper.getById(uploadQueue.actualFileId)
                        if (actualFile != null && actualFile.upload == 0) {
                            // 文件已经上传，从队列中删除
                            YLogImpl.d(TAG, "清理已上传文件: ${uploadQueue.path}")
                            val deleteSuccess = UploadQueueDaoHelper.delete(uploadQueue.uid)
                            if (deleteSuccess) {
                                cleanedCount++
                                YLogImpl.d(TAG, "删除队列记录成功: ${uploadQueue.path}, uid: ${uploadQueue.uid}")
                            } else {
                                YLogImpl.e(TAG, "删除队列记录失败: ${uploadQueue.path}, uid: ${uploadQueue.uid}")
                            }
                        } else {
                            // 文件未上传，保留在队列中
                            validPendingUploads.add(uploadQueue)
                        }
                    } catch (e: Exception) {
                        YLogImpl.e(TAG, "检查文件上传状态异常: ${uploadQueue.path}", e)
                        // 发生异常时保留在队列中
                        validPendingUploads.add(uploadQueue)
                    }
                }
                
                if (cleanedCount > 0) {
                    YLogImpl.i(TAG, "清理了${cleanedCount}个已上传文件")
                }
                
                if (validPendingUploads.isEmpty()) {
                    YLogImpl.i(TAG, "没有需要上传的文件")
                    stopSelf()
                    return@launch
                }
                
                YLogImpl.i(TAG, "开始上传${validPendingUploads.size}个文件")
                
                // 记录正在上传的文件数量
                uploadingCount = validPendingUploads.size
                
                // 逐个启动上传任务（异步）
                for (uploadQueue in validPendingUploads) {
                    uploadFile(uploadQueue)
                }
                
                // 注意：不在这里停止服务，而是在每个文件完成后检查是否所有文件都完成了
                
            } catch (e: Exception) {
                YLogImpl.e(TAG, "上传任务异常", e)
                stopSelf()
            }
        }
    }
    
    /**
     * 上传单个文件
     */
    private suspend fun uploadFile(uploadQueue: UploadQueue) {
        val filePath = uploadQueue.path
        YLogImpl.i(TAG, "开始上传文件: $filePath")
        
        try {
            // 更新状态为正在上传
            UploadManager.updateUploadStatus(filePath, UploadStatus.UPLOADING, 0)
            
            // 更新通知
            updateNotification("正在上传: ${File(filePath).name}")
            
            // 获取文件类型
            val fileType = getFileType(filePath)
            
            // 创建上传监听器
            val listener = object : FileUploadListener {
                override fun onUploadSucceed(s: String?, s1: String?) {
                    YLogImpl.i(TAG, "文件上传成功: $filePath")
                    serviceScope.launch {
                        handleUploadSuccess(uploadQueue)
                    }
                }
                
                override fun onUploadFailed(s: String?) {
                    YLogImpl.e(TAG, "文件上传失败: $filePath, 错误: $s")
                    serviceScope.launch {
                        handleUploadFailure(uploadQueue, s)
                    }
                }
                
                override fun onUploadProgress(progress: Int) {
                    // 更新进度
                    UploadManager.updateUploadStatus(filePath, UploadStatus.UPLOADING, progress)
                    YLogImpl.d(TAG, "文件上传进度: $filePath, $progress%")
                }
            }
            
            // 保存监听器引用
            uploadListeners[filePath] = listener
            
            // 调用上传接口
            RouterUtil.getIMManagerImpl()?.uploadFile(filePath, fileType, listener)
                ?: throw Exception("上传接口不可用")
            
        } catch (e: Exception) {
            YLogImpl.e(TAG, "上传文件异常: $filePath", e)
            handleUploadFailure(uploadQueue, e.message)
        }
    }
    
    /**
     * 处理上传成功
     */
    private suspend fun handleUploadSuccess(uploadQueue: UploadQueue) {
        val filePath = uploadQueue.path
        
        try {
            YLogImpl.d(TAG, "开始处理上传成功: $filePath, actualFileId: ${uploadQueue.actualFileId}")
            
            // 更新ActualFile表的upload字段为0（已上传）
            val actualFile = ActualFileDaoHelper.getById(uploadQueue.actualFileId)
            if (actualFile != null) {
                YLogImpl.d(TAG, "找到ActualFile记录, 当前upload状态: ${actualFile.upload}, 路径: ${actualFile.path}")
                
                actualFile.setUpload(0)  // 标记为已上传
                val success = ActualFileDaoHelper.update(actualFile)
                if (success) {
                    YLogImpl.d(TAG, "更新ActualFile上传状态成功: $filePath, 新状态: ${actualFile.upload}")
                } else {
                    YLogImpl.e(TAG, "更新ActualFile上传状态失败: $filePath")
                }
            } else {
                YLogImpl.e(TAG, "未找到ActualFile记录，actualFileId: ${uploadQueue.actualFileId}")
            }
            
            // 从上传队列中删除
            val deleteSuccess = UploadQueueDaoHelper.delete(uploadQueue.uid)
            if (deleteSuccess) {
                YLogImpl.d(TAG, "从上传队列删除成功: $filePath, uid: ${uploadQueue.uid}")
            } else {
                YLogImpl.e(TAG, "从上传队列删除失败: $filePath, uid: ${uploadQueue.uid}")
            }
            
            // 更新上传状态为成功（会自动从状态映射中移除）
            UploadManager.updateUploadStatus(filePath, UploadStatus.SUCCESS, 100)
            
        } catch (e: Exception) {
            YLogImpl.e(TAG, "处理上传成功异常: $filePath", e)
        } finally {
            // 清理监听器
            uploadListeners.remove(filePath)
            // 检查是否所有文件都完成
            checkAllUploadsComplete()
        }
    }
    
    /**
     * 处理上传失败
     */
    private suspend fun handleUploadFailure(uploadQueue: UploadQueue, errorMessage: String?) {
        val filePath = uploadQueue.path
        
        try {
            // 更新上传状态为失败
            UploadManager.updateUploadStatus(filePath, UploadStatus.FAILED, 0, errorMessage)
            
            // 暂时不从数据库删除，允许用户稍后重试
            // TODO: 可以添加重试机制或者让用户手动重试
            
        } catch (e: Exception) {
            YLogImpl.e(TAG, "处理上传失败异常: $filePath", e)
        } finally {
            // 清理监听器
            uploadListeners.remove(filePath)
            // 检查是否所有文件都完成
            checkAllUploadsComplete()
        }
    }
    
    /**
     * 获取文件类型
     */
    private fun getFileType(filePath: String): Int {
        return when {
            filePath.endsWith(".mp4", ignoreCase = true) -> FILE_TYPE_VIDEO
            filePath.endsWith(".jpg", ignoreCase = true) ||
            filePath.endsWith(".jpeg", ignoreCase = true) ||
            filePath.endsWith(".png", ignoreCase = true) -> FILE_TYPE_IMAGE
            else -> FILE_TYPE_IMAGE  // 默认为图片类型
        }
    }
    
    /**
     * 创建通知渠道
     */
    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                CHANNEL_NAME,
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "文件上传进度通知"
            }
            
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
    }
    
    /**
     * 创建通知
     */
    private fun createNotification(content: String): Notification {
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("文件上传")
            .setContentText(content)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setOngoing(true)
            .build()
    }
    
    /**
     * 更新通知
     */
    private fun updateNotification(content: String) {
        val notificationManager = getSystemService(NotificationManager::class.java)
        notificationManager.notify(NOTIFICATION_ID, createNotification(content))
    }
} 